/** bcmi_frame job scheduler
 *
 *  bcmi_frame job scheduler
 *
 *  @author : huicong
 *  @date : 2008-10-29
 *
 */

#include "JobSystem.h"
#include "BasicHeader.h"

#include <cstring>
#include <string>
#include <sstream>

namespace bcmi_frame
{
    JobSystem::JobSystem(_IN ParallelFrame *_frame): _myFrame(_frame)
    {

    }

    JobSystem::~JobSystem()
    {
        JOB_LIST::iterator _ite;
        for (_ite = _jobList.begin(); _jobList.end() != _ite; ++_ite)
        {
            delete (*_ite);
            (*_ite) = NULL;
        }
        _jobList.clear();
        _myFrame = NULL;
    }

    HRESULT JobSystem::addJob(_IN FrameJob *_jobInstance)
    {
        _jobList.push_back(_jobInstance);
        _jobInstance->linkFrame(_myFrame);
#ifdef LOG_JOB_SYSTEM
        std::stringstream _sbuf;
        _sbuf << "Frame add Job : " << _jobInstance->jobName();
        _myFrame->getLogRecorder()->log(
            H_OK,
            bcmi_frame::JOB_SYSTEM,
            __FUNCSIG__,
            (CSTRING)_sbuf.str().c_str() // CSTRING == char *
            );
#endif //#ifdef LOG_JOB_SYSTEM
        return H_OK;
    }

    HRESULT JobSystem::execute()
    {
        HRESULT hr = H_OK;
        JOB_LIST::iterator _jobIte;
        for (_jobIte = _jobList.begin(); _jobList.end() != _jobIte; ++_jobIte)
        {
#ifdef LOG_JOB_SYSTEM
            _myFrame->getLogRecorder()->log(
                H_OK,
                bcmi_frame::JOB_SYSTEM,
                __FUNCSIG__,
                "JobSystem begin to synchronize(MPI_Barrier) all process before job start"
                );
            _myFrame->getLogRecorder()->logFlush();
#endif //#ifdef LOG_JOB_SYSTEM
            MPI_Barrier(MPI_COMM_WORLD); // synchronize before job start

#ifdef LOG_JOB_SYSTEM
            {
                std::stringstream _buf;
                _buf << "All process has synchronized and start the Job : " << (*_jobIte)->jobName();
                _myFrame->getLogRecorder()->log(
                    H_OK,
                    bcmi_frame::JOB_SYSTEM,
                    __FUNCSIG__,
                    (CSTRING)_buf.str().c_str()
                    );
                _myFrame->getLogRecorder()->logFlush();
            }
#endif //#ifdef LOG_JOB_SYSTEM
            hr = (*_jobIte)->execute();

#ifdef LOG_JOB_SYSTEM
            {
                std::stringstream _buf;
                _buf << "The Job : " << (*_jobIte)->jobName() << " has finished ";
                _myFrame->getLogRecorder()->log(
                    hr,
                    bcmi_frame::JOB_SYSTEM,
                    __FUNCSIG__,
                    (CSTRING)_buf.str().c_str()
                    );
                _myFrame->getLogRecorder()->logFlush();
            }
#endif //#ifdef LOG_JOB_SYSTEM

            if (FAILED(hr))
            {
                //UNDO : do what ? stop or continue ?
            }

#ifdef LOG_JOB_SYSTEM
            _myFrame->getLogRecorder()->log(
                H_OK,
                bcmi_frame::JOB_SYSTEM,
                __FUNCSIG__,
                "JobSystem begin to synchronize(MPI_Barrier) all process after job end"
                );
            _myFrame->getLogRecorder()->logFlush();
#endif //#ifdef LOG_JOB_SYSTEM
            MPI_Barrier(MPI_COMM_WORLD); // synchronize before after job end

#ifdef LOG_JOB_SYSTEM
            _myFrame->getLogRecorder()->log(
                H_OK,
                bcmi_frame::JOB_SYSTEM,
                __FUNCSIG__,
                "All process has synchronized at the end of this cycle"
                );
            _myFrame->getLogRecorder()->logFlush();
#endif //#ifdef LOG_JOB_SYSTEM
        }
        return hr;
    }

}; //namespace bcmi_frame